home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / utility / passw204.zip / PASSWORD.ASM < prev    next >
Assembly Source File  |  1995-12-06  |  22KB  |  453 lines

  1. ;****************************************************************************/
  2. ;*                                                                          */
  3. ;* Module Name: password.asm    version: 2.04,          Date: 12/06/95      */
  4. ;*                                                                          */
  5. ;* Designer(s): Joe Gruessing,                                              */
  6. ;*              Adapted from public domain sources. See "HISTORY" below.    */                         */
  7. ;*                                                                          */
  8. ;* Description: This program is loaded as device in CONFIG.SYS and requires */
  9. ;*              the user to  enter  the "proper" password to continue  boot */
  10. ;*              process. Failure  to enter correct password after "n" tries */
  11. ;*              ("n" as defined below) results  in  a cold reboot. Also, if */
  12. ;*              the  user  input remains  idle for "n" seconds, the  system */
  13. ;*              will be rebooted. Keypresses refresh the timeout counter.   */
  14. ;*                                                                          */
  15. ;*              A success results in the continuation of CONFIG.SYS.  It is */
  16. ;*              intended that this program be used with the multiple config */
  17. ;*              capabilities of MSDOS 6.xx, or DataLight ROM-DOS 6.22.      */
  18. ;*                                                                          */
  19. ;*              Passwords are not case-sensitive in this program!           */
  20. ;*                                                                          */
  21. ;*                                                                          */
  22. ;* Assembler:   Borland Turbo Assembler, v4.0,                              */
  23. ;*                                                                          */
  24. ;*              Tested with ASM Checker by V. Communications                */
  25. ;*                                                                          */
  26. ;****************************************************************************/
  27. ;**************** Copyright (C) 1995, Joseph A. Gruessing Jr. ***************/
  28. ;****************************************************************************/
  29. ;*                                                                          */
  30. ;* HISTORY:                                                                 */
  31. ;*                                                                          */
  32. ;* 07/10/95                                                                 */
  33. ;* 2.00 JAG     Initial adaptation from assembly source "password.asm"      */
  34. ;*              by Cristoph Christ (v1.01 dated 1.11.92) in the Simtel      */
  35. ;*              archive file: "msdos/security/passw11.zip"                  */
  36. ;*                                                                          */
  37. ;*              Changes:                                                    */
  38. ;*                                                                          */
  39. ;*              - removed copyright notice printing to stdout               */
  40. ;*              - changed output strings to be similar to a Unix login      */
  41. ;*              - fixed backspace behavior when at leftmost position        */
  42. ;*              - fixed so input cannot include ascii below space character */
  43. ;*              - user *must* hit return to process entered password        */
  44. ;*              - max password length reduced to 8 characters               */
  45. ;*              - changed read int 21h, function 8 to function 7 so that    */
  46. ;*                ^C would not be printed on screen! Same for function 6    */
  47. ;*              - changed system halt on repeated failures to a reboot      */
  48. ;*              - added timeout capability, if no keypress after n seconds, */
  49. ;*                system will reboot                                        */
  50. ;*              - removed case-sensitivity by borrowing routine from "PW.8" */
  51. ;*                by Bob Montgomery, in the simtel archive file:            */
  52. ;*                           "msdos/security/passwrd6.zip"                  */
  53. ;*                                                                          */
  54. ;* 08/06/95                                                                 */
  55. ;* 2.01 JAG     - replaced my int19 bootstrap with 286 bus reset            */
  56. ;*              - fixed error accepting password after backspace            */
  57. ;*              - fixed indexing on backspace                               */
  58. ;*              - released binary in distribution of company project        */
  59. ;*                                                                          */
  60. ;* 10/15/95                                                                 */
  61. ;* 2.02 JAG     - Cleaned up for general release, redundant code removed,   */
  62. ;*                internal calls rewritten as procedures                    */
  63. ;* 10/16/95                                                                 */
  64. ;* 2.03 JAG     - Fixed index error in Input at "Weiter:" label. Added      */
  65. ;*                reboot message and delay.                                 */
  66. ;*                                                                          */
  67. ;* 12/06/95     - No change to sources. Added FILE_ID.DIZ to archive for    */
  68. ;*                BBS description usage                                     */
  69. ;*                                                                          */
  70. ;****************************************************************************/
  71. ;* NOTE:        THIS CODE IS NOT PUBLIC DOMAIN! AUTHOR RETAINS COPYRIGHT.   */
  72. ;*              YOU MAY DISTRIBUTE, USE, OR MODIFY AS YOU SEE FIT AS LONG   */
  73. ;*              AS COPYRIGHT NOTICE AND ALL  COMMENTS ARE RETAINED IN THE   */
  74. ;*              RESULTING SOURCE FILE. YOU MAY *NOT* SELL THIS SOURCE FOR   */
  75. ;*              PROFIT--EXCEPT AS A PART OF A SHAREWARE COLLECTION.         */
  76. ;****************************************************************************/
  77.  
  78. ; Compiler directives ********************************************************
  79.  
  80. .8086                                   ; base CPU support
  81.  
  82. ; External data references used **********************************************
  83.  
  84. DOSClock       EQU 046ch                ; DOS Clock used for input timeout
  85.  
  86. ; Macros used ****************************************************************
  87.  
  88. PushAll Macro                           ; save all registers
  89.   push ax                               ;
  90.   push bx                               ;
  91.   push cx                               ;
  92.   push dx                               ;
  93.   push si                               ;
  94.   push di                               ;
  95.   push bp                               ;
  96.   push ds                               ;
  97.   push es                               ;
  98. EndM                                    ;
  99.  
  100. PopAll Macro                            ; restore all registers
  101.   pop es                                ;
  102.   pop ds                                ;
  103.   pop bp                                ;
  104.   pop di                                ;
  105.   pop si                                ;
  106.   pop dx                                ;
  107.   pop cx                                ;
  108.   pop bx                                ;
  109.   pop ax                                ;
  110. EndM                                    ;
  111.  
  112.  
  113.  
  114. Code    Segment byte public
  115.         Assume cs:Code, ds:Code, es:Code
  116.  
  117.         org    0
  118.  
  119.  
  120.  
  121. Passwrd proc   far
  122.  
  123. ; Device header **************************************************************
  124.  
  125. Next_Driver    DD 0FFFFFFFFh            ; one device in this file
  126. Attributes     DW 0                     ;
  127. StrategyProc   DW OFFSET Strategy       ; pointer to entry point
  128. CommandsProc   DW OFFSET Commands       ; pointer to proc handling services
  129. Device_Name    DB 'PWAMCXYZ'            ; name of this block device
  130.  
  131.  
  132.  
  133.  
  134. ; Variables ******************************************************************
  135. ;
  136. ; 1. data: {length password},{password},(length input-length password)*{nulls}
  137. ;          {length input},{current length}, length input*{nulls}
  138. ;
  139. ; 2. Encrypted password value determined by Password[x] = Password[x]^x
  140. ;
  141.  
  142. Password       DB 5, 'FWFWQ', 3 dup(0) ; "GUEST" is default build password
  143. Input          DB 8, 0, 8 dup(0)       ; 
  144.  
  145. ; user prompts ---------------------------------------------------------------
  146.  
  147. Prompt         DB 13, 10, 13, 10, 'Password: $'                        
  148. AccessMsg      DB 13, 10, 'Password accepted.', 13, 10, 13, 10, '$'     
  149. InvalidPwd     DB 13, 10, 'Password incorrect.', '$'         
  150. TimeoutMsg     DB 13, 10, 'Timeout occurred.','$'
  151. NoAccess       DB ' Rebooting...','$'
  152.  
  153. ; test flag and # retries ----------------------------------------------------
  154.  
  155. Counter        DB 2                     ; 0,1,2-> 3 tries and reboot
  156. Passed         DB 1                     ; 0= True 1= False
  157.  
  158. ; timeout value and counters -------------------------------------------------
  159.  
  160. Timeout        EQU 0222h                ; 18.2 ticks/s * 30s= 546 ticks
  161. RebootTimeout  EQU 0037h                ; pause 2 seconds before reboot
  162. StartTime      DW 0                     ;
  163. TimeElapsed    DW 0                     ;
  164.  
  165.  
  166.  
  167. ; Request header *************************************************************
  168.  
  169. Params         DD 0                     ; Address of the Request header
  170.  
  171. Request struc                           ;
  172.    Len         db 0                     ;
  173.    Unit        db 0                     ;
  174.    CommandCode db 0                     ;
  175.    Status      dw 0                     ;
  176.    CountUnits  db 0                     ;
  177.    EndAdress   dd 0                     ;
  178.    BIOS_Param  dd 0                     ;
  179.    DriveNr     db 0                     ;
  180.    ConfigError dw 0                     ;
  181. Request ends                            ;
  182.  
  183. Passwrd endp
  184.  
  185. ; Strategy Entry Point *******************************************************
  186.  
  187. Strategy proc far                       ; External Entry Point       
  188.          mov Word Ptr Params, bx        ; Request Header is stored at this
  189.          mov Word Ptr Params + 2, es    ; location
  190.          retf                           ; 
  191. Strategy endp                           ;
  192.  
  193.  
  194.  
  195.  
  196. ; Commands Entry Point *******************************************************
  197.  
  198. Commands proc far                       ;
  199.          cmp cs:passed, 0               ; did user enter correct password?
  200.          je Exit                        ; yes, return to system
  201.          PushAll                        ;
  202.          mov ax, cs                     ; set Datasegment to Codesegment
  203.          mov ds, ax                     ; ""
  204.          mov es, ax                     ; ""
  205.          call Encrypt                   ;
  206. Read:                                   ;
  207.          mov dx, offset Prompt          ;
  208.          call PrintStr                  ; print "Password: " prompt
  209.          call ReadString                ; get user input
  210.          Call ScanLine                  ; test user input
  211.          jz OK                          ; is password ok?
  212.          cmp Counter, 0                 ; no. Any tries left?
  213.          jne Read2                      ; yes. Continue at read2
  214.          mov dx, offset InvalidPwd      ; else
  215.          call PrintStr                  ;  print "Password incorrect"
  216.          call Reboot                    ;  and reboot
  217.          inc Counter                    ; get here only if reboot failed
  218. Read2:                                  ; i know this looks silly :-)
  219.          dec Counter                    ; decrement tries left
  220.          mov dx, offset InvalidPwd      ;
  221.          call PrintStr                  ; print "Password incorrect"
  222.          jmp short Read                 ;
  223. OK:                                     ;
  224.          mov dx, offset AccessMsg       ;
  225.          call PrintStr                  ; print "Password accepted"
  226.          mov passed, 0                  ; flag that user entered correct pwd
  227.          PopAll                         ; get all previous saved Registers
  228. Exit:                                   ;
  229.          retf                           ; return to system
  230.  
  231. Commands endp
  232.  
  233.  
  234.  
  235.  
  236. ; Encryption Procedure -------------------------------------------------------
  237.  
  238. Encrypt  proc near                      ;
  239.          mov di, 1                      ; start from Byte 1 (not 0!!)
  240.          mov cl, byte ptr Password      ; cx= length to encrypt the Password
  241.          cbw                            ; convert byte to word
  242.          mov bx, offset Password        ; bx= ofs(Password) ds= Seg(P.W.)
  243. L1:                                     ;
  244.          mov al, es:[bx + di]           ; al= Password[di]
  245.          mov dx, di                     ; 
  246.          xor al, dl                     ; al= al^di
  247.          mov es:[bx + di], al           ; Password[di]= al
  248.          inc di                         ; next character from String
  249.          loopnz L1                      ; loop if zf= 0, cx > 0
  250.          retn                           ;
  251. encrypt  endp                           ;
  252.  
  253.  
  254.  
  255. ;  Get Character Procedure ---------------------------------------------------
  256.  
  257. GetChar proc near                       ; 08/05/95 JAG - section rewritten
  258.         call GetTime                    ; get the start minutes
  259.         mov cx, TimeElapsed             ;
  260.         mov word ptr StartTime, cx      ;
  261. GetChar2:                               ;
  262.         call GetTime                    ; get the elapsed minutes
  263.         mov cx, TimeElapsed             ;
  264.         sub cx, word ptr StartTime      ; (elapsed - start time)
  265.         cmp cx, Timeout                 ; timeout occurred?
  266.         jbe GetChar3                    ;
  267.         mov dx, offset TimeoutMsg       ; yes,
  268.         call PrintStr                   ; print "Timeout occurred. "
  269.         call Reboot                     ; and call reboot
  270. GetChar3:                               ;
  271.         push dx                         ; preserve maxstrlen
  272.         mov ah, 06h                     ; DOS service 6, subfunction FFh:
  273.         mov dl, 0ffh                    ; get keypress while ignoring ^C's
  274.         int 21h                         ; and don't wait if none available!
  275.         pop dx                          ;
  276.         jz GetChar2                     ; no char was available so loop
  277.         ret                             ;
  278. GetChar endp                            ;
  279.  
  280.  
  281.  
  282. ; Get Time in Ticks Procedure ------------------------------------------------
  283.  
  284. GetTime proc near                       ; 08/05/95 addition: get system time
  285.         PushAll                         ;
  286.         xor ax, ax                      ;
  287.         mov es, ax                      ; simulation segment to 0
  288.         mov cx, es:[DOSClock]           ;
  289.         mov TimeElapsed, cx             ; get time elapsed in ticks
  290.         PopAll                          ;
  291.         retn                            ;
  292. GetTime endp                            ;
  293.  
  294.  
  295.  
  296.  
  297.  
  298. ; Print Character to CRT Procedure -------------------------------------------
  299.  
  300. OutChar proc near                       ;
  301.         push dx                         ; DOS service 2:
  302.         mov ah, 02h                     ; output character in dl to CRT
  303.         mov dl, al                      ;
  304.         int 21h                         ;
  305.         pop dx                          ;
  306.         retn                            ;
  307. Outchar endp                            ;
  308.  
  309.  
  310.  
  311.  
  312. ; Print String to CRT Procedure ----------------------------------------------
  313.  
  314. printstr proc near                      ;
  315.          mov ah, 09H                    ; DOS service 9:
  316.          int 21H                        ; output string at ds:dx ending in '$'
  317.          retn                           ;
  318. printstr endp                           ;
  319.  
  320.  
  321.  
  322. ; Read and Process String ----------------------------------------------------
  323.  
  324. ReadString proc near                    ;
  325.         mov bx, offset Input            ; bx= *Input[0], ptr to max length
  326.         xor dh, dh                      ;
  327.         mov dl, byte ptr es:[bx]        ; dx= Input[0], max length of input
  328.         mov byte ptr es:[bx + 1], 0     ; initialize Input[1] = 0
  329.         xor di, di                      ; offset counter
  330.  Repeat:                                ;
  331.         call GetChar                    ;
  332.         cmp al, 32                      ; above a space ?
  333.         ja Weiter                       ; yes, go get character
  334.         cmp al, 13                      ; a carriage return ?
  335.         je RepeatQuit                   ; yes, go test user's password
  336.         cmp al, 8                       ; a backspace ?
  337.         jne Repeat                      ; no, so ignore
  338.         cmp di, 0                       ; yes, are we at leftmost position ?
  339.         jbe Repeat                      ; yes, so ignore
  340.         dec di                          ; no, do a backspace
  341.         mov ax, di                      ; 
  342.         dec ax                          ; new stringlength after backspace:
  343.         mov byte ptr es:[bx + 1], al    ;       Input[1] = di-1
  344.         mov al, 8                       ; remove last character from screen
  345.         call OutChar                    ; ""
  346.         mov al, 32                      ; by overwriting it with a space
  347.         call OutChar                    ; ""
  348.         mov al, 8                       ; and backing up cursor
  349.         call OutChar                    ; ""
  350.         jmp Repeat                      ; loop until a carriage return
  351.  Weiter:                                ;
  352.         cmp di, dx                      ; current length < maximum length ?
  353.         jge Repeat                      ; no, don't add any more chars!
  354.         mov byte ptr es:[bx + di+2], al ; Input[bx+di+2] = last char in al
  355.         mov ax, di                      ;
  356.         mov byte ptr es:[bx + 1], al    ; Store current length in *Input[1]
  357.         inc di                          ; 
  358.         mov al, '*'                     ; Display a '*' for typed character
  359.         call OutChar                    ; 
  360.         jmp Repeat                      ;
  361.  RepeatQuit:                            ;
  362.         retn                            ; should never get here
  363. ReadString endp                         ;
  364.  
  365.  
  366.  
  367.  
  368. ; Reboot machine by twiddling bus reset. May only work on 286+ ???
  369. ;
  370. ; Note: This can be replace with a standard far jmp reset if does not work
  371. ;       on your platform. Otherwise, this seems elegant.
  372.  
  373. Reboot proc far                         ;
  374.         mov dx, offset NoAccess         ;
  375.         call PrintStr                   ; print "Access Denied. Rebooting..."
  376.         call GetTime                    ; delay momentarily before reboot
  377.         mov cx, TimeElapsed             ; so the user can read the message
  378.         mov word ptr StartTime, cx      ; ""
  379. Reboot2:                                ; ""
  380.         call GetTime                    ; get the elapsed minutes
  381.         mov cx, TimeElapsed             ; ""
  382.         sub cx, word ptr StartTime      ; (elapsed - start time)
  383.         cmp cx, RebootTimeout           ; timeout occurred?
  384.         jbe Reboot2                     ; ""
  385.                                         ; ******* actual reboot ********
  386.         mov al, 0feh                    ; reboot now by pulsing
  387.         mov dx, 064h                    ; .
  388.         out dx, al                      ; the CPU bus reset
  389.         retf                            ; only returns if reset failed
  390. Reboot endp                             ;
  391.  
  392.  
  393.  
  394.  
  395. ScanLine proc near                      ;
  396.          xor ch, ch                     ;
  397.          mov cl, Byte ptr Password      ; number of characters to compare
  398.          mov al, Byte ptr Input  + 1    ; bytes actually inputted by user
  399.          inc al                         ; compensate for input offset        
  400.          sub al, cl                     ; do sizes match ?
  401.          jnz ScanExit                   ; no, so abort
  402.          mov di, offset Password + 1    ; di = ptr to actual password
  403.          mov si, offset Input    + 2    ; si = ptr to user entry
  404.  
  405.          PushAll                        ;
  406. ; *** Case-Sensitivity Section -----------------------------------------------
  407. ;
  408. ; Notes:
  409. ;        1. This section was extracted "as-is" from "PW.8" on SimTel on
  410. ;           08/05/95. See "HISTORY" above for details.
  411. ;
  412. ;           Case-sensitivity is removed by converting any received ASCII
  413. ;           characters in the range 'a' through 'z' to caps.
  414. ;
  415. ;        2. This is recommended for applications in which the user
  416. ;           may not be readily aware of the state of the CAPS LOCK key!
  417. ;
  418. ;        3. For other applications, the input may be treated as case sensitive
  419. ;           by commenting out this section and recompiling.
  420. ;
  421.          mov ax, ds                     ;
  422.          mov es, ax                     ; ES=DS
  423.          mov di, si                     ; DI=SI
  424. ScanCase:                               ;
  425.          cld                            ; clear the direction flag
  426.          lodsb                          ; get char at DS:[SI] to al, inc SI
  427.          cmp al, 'a'                    ; < a ?
  428.          jl ScanStore                   ; yes
  429.          cmp al, 'z'                    ; > z ?
  430.          jg ScanStore                   ; yes
  431.          sub al, 20h                    ; no, convert to uppercase
  432. ScanStore:                              ;
  433.          stosb                          ; store al to ES:[DI], inc DI
  434.          loop ScanCase                  ; loop until CX = 0
  435. ; *** End Case-Sensitivity Section -------------------------------------------
  436. ; ----------------------------------------------------------------------------
  437.          PopAll                         ; restore registers and continue
  438.  
  439.          cld                            ; clear the direction flag
  440.          repe cmpsb                     ; repeat while zf=1+cx > 0 
  441. ScanExit:                               ; amd compare [si] to es:[di]
  442.          retn                           ;
  443. ScanLine endp                           ;
  444.  
  445. ; ****************************************************************************
  446. ; end Password.asm ***********************************************************
  447.  
  448. Code ends
  449. end
  450.  
  451.  
  452.  
  453.